package tr.edu.ege.kipler.satisfiability.container;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import tr.edu.ege.kipler.satisfiability.UnsatisfiableException;
import tr.edu.ege.kipler.satisfiability.container.creational.IndividualFactory;
import tr.edu.ege.kipler.satisfiability.container.operational.ABoxChangeObserver;
import tr.edu.ege.kipler.satisfiability.profile.Logic;
import tr.edu.ege.kipler.syntax.Role;
import tr.edu.ege.kipler.syntax.WorldElement;
import tr.edu.ege.kipler.syntax.atomicformula.ConceptAssertion;
import tr.edu.ege.kipler.syntax.atomicformula.ObjectRoleAssertion;
import tr.edu.ege.kipler.syntax.atomicformula.SameIndividualAssertion;

/**
 * 
 * @author İnanç Seylan
 *
 */
public class SHOIQABox implements ABox {
	private Set<Individual> nominals;

	private GenericABox aBox;

	private IndividualFactory indvFactory = IndividualFactory
			.getFactory(Logic.SHOIQ);

	public SHOIQABox() {
		aBox = new GenericABox(indvFactory, this);
		nominals = new HashSet<Individual>();
	}

	public boolean isNominal(Individual indv) {
		return ((SHOIQIndividual) indv).isNominal();
	}

	public boolean isBlockable(Individual indv) {
		return !isNominal(indv);
	}

	public Set<Individual> getNominals() {
		return nominals;
	}

	public SHOIQABox copy() {
		SHOIQABox result = new SHOIQABox();
		result.indvFactory = this.indvFactory;
		result.aBox = aBox.copy();
		result.aBox.setRepresentedABox(result);
		result.nominals = new HashSet<Individual>();
		// fill the new nominal set from individual instances in the new ABox
		for (Individual nominal : nominals) {
			result.nominals.add(result.getIndividual(nominal.getName()));
		}
		return result;
	}

	public void add(ConceptAssertion ca) throws UnsatisfiableException {
		aBox.add(ca);
	}

	public void add(ObjectRoleAssertion ra) throws UnsatisfiableException {
		aBox.add(ra);
	}

	public void add(SameIndividualAssertion assertion)
			throws UnsatisfiableException {
		aBox.add(assertion);
	}

	public void add(WorldElement formula) throws UnsatisfiableException {
		aBox.add(formula);
	}

	public void addObserver(ABoxChangeObserver observer) {
		aBox.addObserver(observer);
	}

	public boolean contains(ConceptAssertion ca) {
		return aBox.contains(ca);
	}

	public boolean contains(ObjectRoleAssertion ra) {
		return aBox.contains(ra);
	}

	public boolean contains(SameIndividualAssertion ia) {
		return aBox.contains(ia);
	}

	public boolean contains(String individual) {
		return aBox.contains(individual);
	}

	public boolean contains(WorldElement formula) {
		return aBox.contains(formula);
	}

	public boolean containsEdge(Individual node, Individual succCandidate) {
		return aBox.containsEdge(node, succCandidate);
	}

	public boolean containsEdge(Role role, Individual from, Individual to) {
		return aBox.containsEdge(role, from, to);
	}

	public Iterator<Individual> differentIndividualIterator(
			Individual individual) {
		return aBox.differentIndividualIterator(individual);
	}

	public boolean equals(Object obj) {
		if (obj != null && (obj.getClass().equals(this.getClass()))) {
			SHOIQABox other = (SHOIQABox) obj;
			return aBox.equals(other.aBox);
		}
		return false;
	}

	public Set<Role> getEdges(Individual owner, Individual filler) {
		return aBox.getEdges(owner, filler);
	}

	public Set<WorldElement> getFormulas() {
		return aBox.getFormulas();
	}

	public Individual getIndividual(String name) {
		return aBox.getIndividual(name);
	}

	public World getWorld() {
		return aBox.getWorld();
	}

	public int hashCode() {
		return aBox.hashCode();
	}

	public Iterator<Individual> individualIterator() {
		return aBox.individualIterator();
	}

	public boolean isSatisfiable() {
		return aBox.isSatisfiable();
	}

	public Iterator<Individual> neighborIterator(Individual indv) {
		return aBox.neighborIterator(indv);
	}

	public Iterator<ObjectRoleAssertion> neighborIterator(Role role,
			Individual owner) {
		return aBox.neighborIterator(role, owner);
	}

	public Iterator<Individual> predecessorIterator(Individual filler) {
		return aBox.predecessorIterator(filler);
	}

	public Iterator<ObjectRoleAssertion> predecessorIterator(Role role,
			Individual filler) {
		return aBox.predecessorIterator(role, filler);
	}

	public void remove(String name) {
		aBox.remove(name);
	}

	public Iterator<Individual> sameIndividualIterator(Individual individual) {
		return aBox.sameIndividualIterator(individual);
	}

	public void setHasClash(boolean hasClash) {
		aBox.setHasClash(hasClash);
	}

	public Iterator<Individual> successorIterator(Individual owner) {
		return aBox.successorIterator(owner);
	}

	public Iterator<ObjectRoleAssertion> successorIterator(Role role,
			Individual owner) {
		return aBox.successorIterator(role, owner);
	}

	public String toString() {
		return aBox.toString();
	}

	public void setWorld(World world) {
		aBox.setWorld(world);
	}

}
